package com.sdonkey.score.filter;

import com.alibaba.fastjson.JSONObject;
import com.sdonkey.score.bean.LoginReturnBean;
import com.sdonkey.score.constants.RedisKey;
import com.sdonkey.score.util.CookieUtil;
import com.sdonkey.score.util.ResponseUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.util.HashSet;
import java.util.Set;

/**
 * session验证filter
 *
 * @author chenwh
 */
public class SecurityCheckFilter implements Filter {


    //	JedisPool jedisPool = (JedisPool) SpringContextUtils.getBeanById("messageService");
    @Autowired
    JedisPool jedisPool;


    private static final Logger log = LoggerFactory.getLogger(SecurityCheckFilter.class);

    private Set<String> noNeedCheckUrlSet;// 无需验证的url集合


    public SecurityCheckFilter() {

    }

    @Override
    public void init(FilterConfig config) throws ServletException {


        ServletContext sc = config.getServletContext();

        WebApplicationContext cxt = WebApplicationContextUtils.getWebApplicationContext(sc);

        if (cxt != null && cxt.getBean(JedisPool.class) != null && jedisPool == null) {

            jedisPool = (JedisPool) cxt.getBean(JedisPool.class);

        }
        // 无需验证的url集合
        noNeedCheckUrlSet = new HashSet<String>();
        noNeedCheckUrlSet.add("/dologin");
        noNeedCheckUrlSet.add("/sendEmail");
        noNeedCheckUrlSet.add("/ajaxRegister");
        noNeedCheckUrlSet.add("/uploadImgs");

        noNeedCheckUrlSet.add("/existEmail");//“忘记密码” 下的请求
        noNeedCheckUrlSet.add("/sendEmailVerCode");
        noNeedCheckUrlSet.add("/checkEmail");
        noNeedCheckUrlSet.add("/validateCode");
        noNeedCheckUrlSet.add("/gainEmailAndName");
        noNeedCheckUrlSet.add("/reset/password");
        noNeedCheckUrlSet.add("/checkEmail");
        noNeedCheckUrlSet.add("/loginOut");


        noNeedCheckUrlSet.add("/controller");
        noNeedCheckUrlSet.add("/regist");
        noNeedCheckUrlSet.add("/static");
        noNeedCheckUrlSet.add("/views/login");
        noNeedCheckUrlSet.add("/views/master");
        noNeedCheckUrlSet.add("/views/message");
        noNeedCheckUrlSet.add("/findCode");//发送验证码
        noNeedCheckUrlSet.add("/writeEmail");
        noNeedCheckUrlSet.add("/resendEmailCode");
        noNeedCheckUrlSet.add("/getEmailvalidateCode");
        noNeedCheckUrlSet.add("/registerLoginInfo");
        noNeedCheckUrlSet.add("/getvalidateCode");
        noNeedCheckUrlSet.add("/authenticate");
        noNeedCheckUrlSet.add("/sendEmailCode");
        noNeedCheckUrlSet.add("/validateCode");
        noNeedCheckUrlSet.add("/getvalidateCode");
        noNeedCheckUrlSet.add("/getUser");
        noNeedCheckUrlSet.add("/getCompanyLogo");//获取公司logo
        noNeedCheckUrlSet.add("/getSystemInfo");
        noNeedCheckUrlSet.add("/getInboxList");//站内信

        noNeedCheckUrlSet.add("/uploadChaImg");//基本信息上传图片

        noNeedCheckUrlSet.add("/checkMemberName");//审核状态下  昵称去重
        noNeedCheckUrlSet.add("/updateBasicInfo");//审核状态下 修改基本信息
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest hreq = (HttpServletRequest) request;
        HttpServletResponse hres = (HttpServletResponse) response;
        String origin = hreq.getHeader("Origin");
        if (StringUtils.isBlank(origin)) {
            String referer = hreq.getHeader("referer");
            if (StringUtils.isNotBlank(referer)) {
                try {
                    URI uri = URI.create(referer);
                    if (uri != null) {
                        referer = uri.getScheme() + "://" + uri.getHost();
                        if (uri.getPort() > 0) {
                            referer = referer + ":" + uri.getPort();
                        }
                    }
                } catch (Exception e) {

                }
            }
            origin = referer;
        }
        log.info("【请求域名】 " + origin);
        if (StringUtils.isNotBlank(origin)) {
            hres.setHeader("Access-Control-Allow-Origin", origin);
        }
//		hres.setHeader("Access-Control-Allow-Origin", "*"); //tomcat添加跨域访问功能-Access-Control-Allow-Origin:*

        hres.setHeader("Access-Control-Allow-Credentials", "true");
        hres.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS");
        hres.setHeader("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
        hres.setHeader("Access-Control-Max-Age", "3600");
        hres.setCharacterEncoding("utf-8");
//		hres.setContentType("application/json;charset=utf-8");


        // 确保浏览器不缓存页面数据
        hres.setHeader("Cache-Control", "no-cache");
        hres.setHeader("Cache-Control", "no-store");
        hres.setDateHeader("Expires", 0);
        hres.setHeader("Pragma", "no-cache");

        log.debug("【请求地址】" + hreq.getRequestURI());
        // 验证开始
        if (!noNeedDecideURL(hreq)) {
            String cookieId = CookieUtil.getCookie(hreq, "advId");
            log.info("请求的cookieId为" + cookieId);
            if (StringUtils.isBlank(cookieId)) {
                log.info("用户未登录！！！");
                hres.getWriter().print(ResponseUtil.createError("NOT_LOGIN","用户未登录"));
                return;
            }
            Jedis jedis = jedisPool.getResource();
            String value = jedis.get(RedisKey.user_login_id + cookieId);
            log.info("获取用户信息redis " + value);
            if (StringUtils.isBlank(value)) {
                JSONObject result = new JSONObject();
                JSONObject error = new JSONObject();
                hres.getWriter().print(ResponseUtil.createError("NOT_LOGIN","用户未登录"));
                return;
            }
            JSONObject advUser = JSONObject.parseObject(value);
            LoginReturnBean loginReturnBean = JSONObject.toJavaObject(advUser, LoginReturnBean.class);
            request.setAttribute("advertiser", loginReturnBean);
            //刷新缓存
            jedis.setex(RedisKey.user_login_id + cookieId, 30 * 60, JSONObject.toJSONString(loginReturnBean));
        }
        chain.doFilter(request, response);

    }

    private int checkBack(HttpSession httpSession) {
        //if (httpSession.getAttribute("advId") == null) {
        int flag = -1;
        //用户未登录
        if (httpSession.getAttribute("donkeynum") == null || httpSession.getAttribute("advId") == null) {
            flag = 1;
        }
        //用户待审核状态
        if ("2".equals(httpSession.getAttribute("checkStatus"))) {
            flag = 2;
        }
        //用户未通过状态
        if ("0".equals(httpSession.getAttribute("checkStatus"))) {
            flag = 0;
        }
        return flag;
    }

    /**
     * 哪些请求不需要拦截
     *
     * @param hreq
     * @return
     */
    private boolean noNeedDecideURL(HttpServletRequest hreq) {
        // 如果访问的url为null，则无需验证
        String servletPath = hreq.getServletPath();
        if (servletPath == null) {
            return true;
        }

        for (String str : noNeedCheckUrlSet) {
            if (servletPath.contains(str)) {
                return true;
            }
        }
//		//静态js css不验证，注册找回密码不验证
        if (hreq.getServletPath().contains("/advWeb/controller") || hreq.getServletPath().contains("/advWeb/views/login") || hreq.getServletPath().contains("/advWeb/static") || (hreq.getServletPath().contains("/password"))) {
            return true;
        }
//		// 无需验证集合包含访问的url，则无通过
//		if (noNeedCheckUrlSet.contains(hreq.getServletPath())) {
//			return true;
//		}
        return false;
    }


    /**
     * 输出JSON
     *
     * @param response
     * @author SHANHY
     * @create 2017年4月4日
     */
    private void writeJson(JSONObject json, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            out = response.getWriter();
            out.write(json.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
    }